package cn.ztelovecly.springboot.framework.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 *
 */
public class DateUtil {

	public static final int MILLISECONDS_OF_DAY = 24 * 60 * 60 * 1000;

	/**
	 * 将输入的时间转换为标准时间字符串
	 * @param date
	 * @return
	 */
	public static String dateToString(Date date) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm");
		return dateFormat.format(date);
	}

	/**
	 * 将输入的时间转换为相对当前时刻的时间。
	 * @return
	 */
	public static String dateToLocalString(Date date) {
		long reduce = new Date().getTime() - date.getTime();
		if(reduce <= 600000) {
			if(reduce <= 60000) {
				return reduce/1000 + "秒前";
			} else {
				return (reduce / 60000) + "分钟前";
			}
		}
		Calendar now = Calendar.getInstance();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		if(calendar.get(Calendar.YEAR) == now.get(Calendar.YEAR)) {
			if(calendar.get(Calendar.MONTH) == now.get(Calendar.MONTH)) {
				if(calendar.get(Calendar.DATE) == now.get(Calendar.DATE)) {
					SimpleDateFormat dateFormat = new SimpleDateFormat("今天 HH:mm");
					return dateFormat.format(calendar.getTime());
				}
				if(calendar.get(Calendar.DATE) == now.get(Calendar.DATE) - 1) {
					SimpleDateFormat dateFormat = new SimpleDateFormat("昨天 HH:mm");
					return dateFormat.format(calendar.getTime());
				}
				if(calendar.get(Calendar.DATE) == now.get(Calendar.DATE) - 2) {
					SimpleDateFormat dateFormat = new SimpleDateFormat("前天 HH:mm");
					return dateFormat.format(calendar.getTime());
				}
			}
			SimpleDateFormat dateFormat = new SimpleDateFormat("MM月dd日 HH:mm");
			return dateFormat.format(calendar.getTime());
		} else {
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm");
			return dateFormat.format(calendar.getTime());
		}
	}

	/**
	 * 转换月份日期。  <br/>
	 * 例如：输入201406 & true，返回 2014-06-01 00:00:00 <br/>
	 * 例如：输入201406 & false，返回 2014-06-30 23:59:59 <br/>
	 * 例如：输入201413 & false，返回 2015-01-31 23:59:59 <br/>
	 * @param value     6位长度的月份值
	 * @param isHead    是否返回月初的时间（是，月初；否，月尾）
	 * @return          相应的时间
	 * @throws IllegalArgumentException     该方法只接受长度为6的字符串
	 * @throws NumberFormatException        该方法只接受能转换为数字的字符串
	 */
	public static Date transferMonth(String value, Boolean isHead){
		if(value == null || value.length() != 6) {
			throw new IllegalArgumentException("时间的长度必须为6位");
		}
		int iTime;
		try {
			iTime = Integer.parseInt(value);
		} catch (NumberFormatException e) {
			throw new NumberFormatException(value + "不能转为一个合法的数字");
		}

		SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
		Date date = null;

		// 如果是获得月初的时间
		try {
			if (isHead) {
				value = iTime + "01 00:00:00";
				date = format.parse(value);
			} else {
				value = (iTime + 1) + "01 00:00:00";
				date = new Date(format.parse(value).getTime() - 1000);
			}
		}catch (ParseException ignored) {
			//这里的错误已经在前面被处理掉了。
		}
		return date;
	}

	/**
	 * 转换日期。  <br/>
	 * 例如：输入20140601 & true，返回 2014-06-01 00:00:00 <br/>
	 * 例如：输入20140630 & false，返回 2014-06-30 23:59:59 <br/>
	 * 例如：输入20141331 & false，返回 2015-01-31 23:59:59 <br/>
	 * @param value     8位长度的日期值
	 * @param isHead    是否返回日初的时间（是，日初；否，日尾）
	 * @return          相应的时间
	 * @throws IllegalArgumentException     该方法只接受长度为8的字符串
	 * @throws NumberFormatException        该方法只接受能转换为数字的字符串
	 */
	public static Date transferDate(String value, Boolean isHead){
		if(value == null || value.length() != 8) {
			throw new IllegalArgumentException("时间的长度必须为8位");
		}
		int iTime;
		try {
			iTime = Integer.parseInt(value);
		} catch (NumberFormatException e) {
			throw new NumberFormatException(value + "不能转为一个合法的数字");
		}

		SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
		Date date = null;

		// 如果是获得月初的时间
		try {
			if (isHead) {
				value = iTime + " 00:00:00";
				date = format.parse(value);
			} else {
				value = (iTime + 1) + " 00:00:00";
				date = new Date(format.parse(value).getTime() - 1000);
			}
		}catch (ParseException ignored) {
			//这里的错误已经在前面被处理掉了。
		}
		return date;
	}

	/**
	 * 获取当地时区一天开始的时刻。注意时区的问题。
	 * @param date      要处理的时间
	 * @return          输入时间当天第一秒的时间
	 */
	public static Date getBeginOfDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);

		return calendar.getTime();
	}

	/**
	 * 获取当地时区一天结束的时刻
	 * @param date      要处理的时间
	 * @return          输入时间当天最后一秒的时间
	 */
	public static Date getEndOfDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);

		return calendar.getTime();
	}

	/**
	 * 获取当地时区一天开始的时刻。注意时区的问题。
	 * @param date      要处理的时间
	 * @return          输入时间当天第一秒的时间
	 */
	public static Date getBeginOfHour(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);

		return calendar.getTime();
	}

	/**
	 * 获取当地时区一天结束的时刻
	 * @param date      要处理的时间
	 * @return          输入时间当天最后一秒的时间
	 */
	public static Date getEndOfHour(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);

		return calendar.getTime();
	}

	/**
	 * 计算两个日期之间的天数差
	 * @param beginDate     开始的日期
	 * @param endDate       结束的日期
	 * @return              相关的天数
	 */
	public static int getNumberOfDays(Date beginDate, Date endDate) {
		Long begin = beginDate.getTime() / MILLISECONDS_OF_DAY;
		Long end = endDate.getTime() / MILLISECONDS_OF_DAY;
		Long days =  (end - begin);
		return days.intValue();
	}

    /**
     * 日期类型格式化Date→String
     * @param dateToFormat 需要格式化的日期
     * @param format 格式化
     * @return 格式化后的字符串
     */
    public static String formatDate(Date dateToFormat, String format){
        SimpleDateFormat formatter = new SimpleDateFormat(format);
	    return formatter.format(dateToFormat);
    }

	/**
	 * 按指定格式获取当前时间
	 * @param format    使用的格式
	 * @return          日期字符串
	 */
	public static String formatDate(String format) {
		return formatDate(new Date(), format);
	}

	public static Integer getPeriodId(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
		String str = sdf.format(date);
		return Integer.decode(str);
	}

    public static Integer getDateId(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String str = sdf.format(date);
        return Integer.decode(str);
    }
}
